Programs written in languages such as Java™ may sometimes be used to implement business applications which are used for years after the programs were originally written. During the lifetime of such applications, many new features and enhancements may be introduced into new versions of the programming language, with the intention of enabling programmers to accomplish various application tasks more easily or more concisely than may have been possible with earlier versions. For example, enhancements to the type management mechanisms of a programming language may be implemented, and/or new features such as lambda expressions may be added. Programs written before the introduction of the enhancements may, of course, continue to run without any changes. However, in many situations, it may be beneficial to modify or refactor at least some portions of such programs to take advantage of the new capabilities of the programming language.
Such refactoring transformations may make the source code more readable and therefore easier to understand and debug, for example, and at least in some cases may make the code safer by resolving potential ambiguities. At least some programs written after the introduction of the enhancements into the programming language may also benefit from such transformations, especially because not all the programmers involved may be aware of (or fluent in the use of) the new features. However, as the sophistication of the enhancements and new features of the language increases, and multiple related code transformations that could impact each other in subtle ways become feasible, identifying which particular refactoring opportunities can be implemented may become a non-trivial task.